package light.mvc.service.workflow.impl;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.zip.ZipInputStream;

import light.mvc.dao.BaseDaoI;
import light.mvc.model.workflow.TformTemplate;
import light.mvc.pageModel.base.PageFilter;
import light.mvc.pageModel.workflow.FormTemplate;
import light.mvc.pageModel.workflow.MyActivityCoordinates;
import light.mvc.pageModel.workflow.ProcessDefinitionModel;
import light.mvc.service.workflow.ProcessDefinitionServiceI;

import org.jbpm.api.ProcessDefinition;
import org.jbpm.api.ProcessDefinitionQuery;
import org.jbpm.api.ProcessEngine;
import org.jbpm.api.ProcessInstance;
import org.jbpm.api.model.ActivityCoordinates;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ProcessDefinitionServiceImpl implements ProcessDefinitionServiceI {

	@Autowired
	private BaseDaoI<TformTemplate> formTemplateDao;

	@Autowired
	private ProcessEngine processEngine;

	public List<ProcessDefinitionModel> findAllLatestVersions() {
		List<ProcessDefinitionModel> ul = new ArrayList<ProcessDefinitionModel>();
		// 查询出所有流程定义，把最大的版本排序最后面
		List<ProcessDefinition> allList = processEngine.getRepositoryService()//
				.createProcessDefinitionQuery()//
				.orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//
				.list();

		// 过滤出最新的版本
		Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>();
		for (ProcessDefinition pd : allList) {
			map.put(pd.getKey(), pd);
		}
		for (ProcessDefinition processDefinition : map.values()) {
			ProcessDefinitionModel pModel =new ProcessDefinitionModel();
			BeanUtils.copyProperties(processDefinition, pModel);
			ul.add(pModel);
		}
		return ul;
	}

	public void deployZip(ZipInputStream zipInputStream) {
		processEngine.getRepositoryService()//
				.createDeployment()//
				.addResourcesFromZipInputStream(zipInputStream)//
				.deploy();
	}

	public void deleteByKey(String key) {
		// 1，查询出指定key的所有版本的流程定义
		List<ProcessDefinition> list = processEngine.getRepositoryService()//
				.createProcessDefinitionQuery()//
				.processDefinitionKey(key)//
				.list();

		// 2，循环删除
		for (ProcessDefinition pd : list) {
			processEngine.getRepositoryService().deleteDeploymentCascade(pd.getDeploymentId());
		}
	}

	public InputStream getProcessImageResourceAsStream(String pdId) {
		// 查询出ProcessDefinition对象
		ProcessDefinition pd = processEngine.getRepositoryService()//
				.createProcessDefinitionQuery()//
				.processDefinitionId(pdId)//
				.uniqueResult();

		// 得到图片资源并返回
		return processEngine.getRepositoryService().getResourceAsStream(pd.getDeploymentId(), pd.getImageResourceName());
	}
	
	public ProcessDefinition getProcessDefinition(String pdId) {
		// 查询出ProcessDefinition对象
		ProcessDefinition pd = processEngine.getRepositoryService()//
				.createProcessDefinitionQuery()//
				.processDefinitionId(pdId)//
				.uniqueResult();
		return pd;
	}

	@Override
	public String getProcessDefinitionId(String proccessInstanceId) {
		ProcessInstance pi = processEngine.getExecutionService().findProcessInstanceById(proccessInstanceId);
		if (pi != null) {
			return pi.getProcessDefinitionId();
		}
		return null;
	}

	private String orderHql(PageFilter ph) {
		String orderString = "";
		if ((ph.getSort() != null) && (ph.getOrder() != null)) {
			orderString = " order by t." + ph.getSort() + " " + ph.getOrder();
		}
		return orderString;
	}

	@Override
	public Long count(FormTemplate formTemplate, PageFilter ph) {
		Map<String, Object> params = new HashMap<String, Object>();
		String hql = " from TformTemplate t ";
		return this.formTemplateDao.count("select count(*) " + hql, params);
	}

	@Override
	public List<MyActivityCoordinates> getActivityCoordinates(String piId) {
		List<MyActivityCoordinates> activityCoordinates = new ArrayList<MyActivityCoordinates>();
		String pdId = getProcessDefinitionId(piId);
		if (pdId != null) {
			ProcessInstance pi = processEngine.getExecutionService().findProcessInstanceById(piId);
			Set<String> activitySet = pi.findActiveActivityNames();
			for (String activityName : activitySet) {
				ActivityCoordinates coordinate = processEngine.getRepositoryService().getActivityCoordinates(pdId, activityName);
				MyActivityCoordinates myActivityCoordinates = new MyActivityCoordinates();
				myActivityCoordinates.setX(coordinate.getX());
				myActivityCoordinates.setY(coordinate.getY());
				myActivityCoordinates.setWidth(coordinate.getWidth());
				myActivityCoordinates.setHeight(coordinate.getHeight());
				activityCoordinates.add(myActivityCoordinates);
			}
			return activityCoordinates;
		}else{
			return null;
		}
	}

}
